import 'package:dio/dio.dart';
import 'package:flutter_enjoy_plus_01/utils/Toast.dart';

import '../constants/index.dart';

class RequestDio {
  // 1. 创建Dio实例
  final Dio _dio = Dio();

  // 2.定义构造函数
  RequestDio() {
    // 3.针对dio的基础地址进行设置
  _dio
    .options.baseUrl = GlobalVariable.BASE_URL; // 设置基础地址
    _dio.options.receiveTimeout =
        const Duration(seconds: GlobalVariable.NET_WORK_TIME); // 接收时间
    _dio.options.sendTimeout =
        const Duration(seconds: GlobalVariable.NET_WORK_TIME); // 发送超时时间

    // 4.添加拦截器
    _registerInterceptors();
  }

  // 6.封装get请求
  get(String url, { Map<String, dynamic>? params }) async {
    final res =  await _dio.get(url, queryParameters: params);
    return _handleReturn(res);
  }
  // 7.封装post请求
  post(String url, { Map<String, dynamic>? data}) async {
    final res =  await _dio.post(url, queryParameters: data);
    return _handleReturn(res);
  }
  // 8.封装delete请求
  delete(String url, { Map<String, dynamic>? data}) async {
    final res =  await _dio.delete(url, queryParameters: data);
    return _handleReturn(res);
  }
  // 9.封装put请求
  put(String url, { Map<String, dynamic>? data}) async {
    final res =  await _dio.put(url, queryParameters: data);
    return _handleReturn(res);
  }

  // 封装统一处理请求返回的方法
  _handleReturn(Response<dynamic> res){
    if(res.data['code'] == 10000){
      // 业务请求成功
      return res.data['data'];
    }
    // 业务请求失败 抛出异常
    throw Exception(res.data['message']);
    // TODO 错误处理
  }

  // 5.封装拦截器请求
  _registerInterceptors() {
    _dio.interceptors.add(
  InterceptorsWrapper(
    // 请求拦截器
    onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
      // 如果你想完成请求并返回一些自定义数据，你可以使用 `handler.resolve(response)`。
      // 如果你想终止请求并触发一个错误，你可以使用 `handler.reject(error)`。
      return handler.next(options);
    },
    // 响应拦截器
    onResponse: (Response response, ResponseInterceptorHandler handler) {
      // 如果你想终止请求并触发一个错误，你可以使用 `handler.reject(error)`。
      // 如果你想完成请求并返回一些自定义数据，你可以使用 `handler.resolve(response)`。
      // 有请求成功响应 和 请求 失败响应
      // 针对http状态码结果 
      if(response.statusCode! >= 200 && response.statusCode! < 300){
        // 请求成功
        return handler.next(response);
      } else {
        // 请求失败 401 404 500 等
        // TODO 401授权失败
        // 提示用户
        PromptAction.showFailToast('请求失败');
        // 返回一个错误的Future
        return handler.reject(DioException(
          requestOptions: response.requestOptions,
        ));
      }
      
    },
    // 错误处理
    onError: (DioException error, ErrorInterceptorHandler handler) {
      // 如果你想完成请求并返回一些自定义数据，你可以使用 `handler.resolve(response)`。
      return handler.next(error);
    },
  ),
);
  }
}

final requestDio = RequestDio();